
/**
 * 可用代理ip池
 * @constructor
 */
module.exports = new UsableProxyPool();

function UsableProxyPool(){
    //单例模式
    if(typeof arguments.callee.instance === "object"){
        return arguments.callee.instance;
    }
    this.denyProxyList = {
        "119.188.9.115":{},
	"123.103.58.59":{}
    }; //被禁止使用的代理，可能原因有 1、出口ip不一致
    this.proxylist = {} ;
    this.useidList = {}; //被使用代理的 随机id列表 {useid}:{setTimeout}
	this.userProxyList = {};////被使用代理的列表 {useid}:{proxy}
    this.useOneWeight = 50; //一个用户占用代理 权重对应的增加值
    this.failOneWeight = 100; //代理失败是 权重对应的增加值
    this.autoReleaseTime = 15000;//超时后自动释放已使用的代理
    this.util = require("../util/util.js");
    this.stablePort = [80,8080,3128,9999,8090,8000,9000,8081,81,8888,8118];



    arguments.callee.instance = this;
}

/**
 * 增加代理
 * @param proxy
 */
UsableProxyPool.prototype.add = function(proxy){
//    http://localhost:1540/usable_proxy_pool/add?proxy={"host":"127.0.0.1","port":"8080","resBaiduTime":"540"}
    var k = proxy.host+":"+proxy.port;
    if(this.denyProxyList[proxy.host]!=undefined){
        return false;
    }
    proxy.weight = Number(proxy.resBaiduTime);
    if(isNaN(proxy.weight)){
        proxy.weight = 0;
    }
    if(this.stablePort.indexOf(parseInt(proxy.port))>=0){
        proxy.weight = proxy.resBaiduTime-350;
    }
    var regionId = proxy.regionId;
    if (typeof this.proxylist[regionId] === "undefined"){
        this.proxylist[regionId] = new Array();
    }
    //判断是否存在
    var hasProxy = this.find(proxy);
    if(hasProxy){ //存在代理，主要处理的是权重
//        var oldProxy = this.proxylist[hasProxy.regionId][hasProxy.index];
//        if(oldProxy.weight - oldProxy.resTime > 0){
//            proxy.weight = proxy.weight + oldProxy.weight - oldProxy.resTime;
//        }
//        this.proxylist[regionId][hasProxy.index] = proxy;
        if(hasProxy.regionId!=proxy.regionId){ // 出口ip不一致的
            console.log("出口IP不一致 "+k)
            this.denyProxyList[proxy.host] = proxy;
            this.del(proxy);
        }
    }else{
        this.proxylist[regionId].push(proxy);
    }
}

UsableProxyPool.prototype.find = function(proxy){
    for(var i in this.proxylist){
        var len = this.proxylist[i].length;

        for(var j=0;j<len;j++){
            var p = this.proxylist[i][j];
            if(p.host == proxy.host && p.port==proxy.port){
                return {"regionId":i,"index":j}
            }
        }//end for
    }
    return null;
}

/**
 * 删除代理
 * @param proxy
 */
UsableProxyPool.prototype.del = function(proxy){
    var hasProxy = this.find(proxy);
    if(hasProxy){
        this.proxylist[hasProxy.regionId].splice(hasProxy.index,1);
    }
}

UsableProxyPool.prototype.getList = function(){
    return {list:this.proxylist,userProxyList:this.userProxyList};
}

/**
 * 获取一个指定地区代理
 * @param regionId
 */
UsableProxyPool.prototype.get = function(regionId){
    if(this.proxylist[regionId]==undefined){
        return null;
    }
    this.sort(regionId);
    var proxy = this.proxylist[regionId][0];
    if( proxy == undefined){
        return null;
    }else{
        this.incrWeight(proxy,this.useOneWeight);
        var newProxy = this.util.clone(proxy);

        //给这次的获取做一个标示
        newProxy.useid = this.util.s8();

        //超时，自动释放
        var tmpThis = this;
		this.userProxyList[newProxy.useid] = newProxy;
        this.useidList[newProxy.useid] = setTimeout(function(){
            console.log("自动释放ip"+newProxy.host+" "+newProxy.useid);
            tmpThis.release(newProxy);
        },this.autoReleaseTime);

        return newProxy;
    }
}

/**
 * 获取一个指定地区代理
 * @param regionId
 */
UsableProxyPool.prototype.getAndExclude = function(regionId,excudeProxy){
    if(this.proxylist[regionId]==undefined){
        return null;
    }
    var proxy = null;

    this.sort(regionId);
    var len = 0;
    if(this.proxylist[regionId]!=undefined){
        len = this.proxylist[regionId].length;
    }
    for(var i=0;i<len;i++){
        if(this.proxylist[regionId][i].host!= excudeProxy.host){
            proxy = this.proxylist[regionId][i];
            break;
        }
    }

    if( proxy == undefined || proxy==null){
        return null;
    }else{
        this.incrWeight(proxy,this.useOneWeight);
        var newProxy = this.util.clone(proxy);

        //给这次的获取做一个标示
        newProxy.useid = this.util.s8();

        //超时，自动释放
        var tmpThis = this;
        this.userProxyList[newProxy.useid] = newProxy;
        this.useidList[newProxy.useid] = setTimeout(function(){
            console.log("自动释放ip"+newProxy.host+" "+newProxy.useid);
            tmpThis.release(newProxy);
        },this.autoReleaseTime);

        return newProxy;
    }
}

/**
 * 代理请求网络失败是，需要对代理降级
 * @param proxy
 */
UsableProxyPool.prototype.fail = function(proxy){
    this.incrWeight(proxy,this.failOneWeight);
}

UsableProxyPool.prototype.release = function(proxy){
    if(this.useidList[proxy.useid] != undefined){
        clearTimeout(this.useidList[proxy.useid]);
		delete this.userProxyList[proxy.useid];
        delete this.useidList[proxy.useid];
        this.decrWeight(proxy,this.useOneWeight);
    }
}

UsableProxyPool.prototype.releaseForUserid = function(useid){
    if(this.userProxyList[useid] != undefined){
		var proxy = this.userProxyList[useid];
		this.release(proxy);
    }
}

/**
 * 提高权重
 * @param proxy
 */
UsableProxyPool.prototype.decrWeight = function(proxy,weight){
    var regionId = proxy.regionId;
    var hasProxy = this.find(proxy);
    if(hasProxy){
        var proxy = this.proxylist[regionId][hasProxy.index];
        if(proxy.weight>proxy.resTime){
            proxy.weight -= weight;
        }
    }
}

/**
 * 降低权重
 * @param proxy
 */
UsableProxyPool.prototype.incrWeight = function(proxy,weight){
    var regionId = proxy.regionId;
    var hasProxy = this.find(proxy);
    if(hasProxy){
        this.proxylist[regionId][hasProxy.index]["weight"] += weight;
    }
}

UsableProxyPool.prototype.sort = function(regionId){
    if(this.proxylist[regionId] instanceof Array){
        this.proxylist[regionId].sort(this.util.compareObjectFn("weight"));
    }
}
